package com.aggron.service.impl;

import com.aggron.dao.SysDeptMapper;
import com.aggron.dao.SysUserMapper;
import com.aggron.entity.SysDept;
import com.aggron.exception.ParamException;
import com.aggron.params.DeptParams;
import com.aggron.service.ISysDeptService;
import com.aggron.util.BeanValidator;
import com.aggron.util.CollectionsUtil;
import com.aggron.util.LevelUtil;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.base.Preconditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author liuhuan
 * @since 2018-06-02
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public void save(DeptParams deptParams) {
        BeanValidator.check(deptParams);
        if(checkExist(deptParams.getParentId(),deptParams.getName(),deptParams.getId())){
            throw new ParamException("同一层级下存在相同的部门");
        }
        SysDept sysDept= SysDept.builder().name(deptParams.getName()).parentId(deptParams.getParentId()).seq(deptParams.getSeq()).remark(deptParams.getRemark()).build();
        sysDept.setLevel(LevelUtil.calculateLevel(getLevel(deptParams.getParentId()),deptParams.getParentId()));
        sysDept.setOperator("admin");//TODO
        sysDept.setOperateIp("127.0.0.1");//TODO
        sysDept.setOperateTime(new Date());
        sysDeptMapper.insert(sysDept);
    }

    @Override
    public void update(DeptParams deptParams) {
        BeanValidator.check(deptParams);
        if(checkExist(deptParams.getParentId(),deptParams.getName(),deptParams.getId())){
            throw new ParamException("同一层级下存在相同的部门");
        }
        SysDept before=sysDeptMapper.selectById(deptParams.getId());
        Preconditions.checkNotNull(before,"待更新的部门不存在");
        SysDept after= SysDept.builder().id(deptParams.getId()).name(deptParams.getName()).parentId(deptParams.getParentId()).seq(deptParams.getSeq()).remark(deptParams.getRemark()).build();
        after.setLevel(LevelUtil.calculateLevel(getLevel(deptParams.getParentId()),deptParams.getParentId()));
        after.setOperator("admin");//TODO
        after.setOperateIp("127.0.0.1");//TODO
        after.setOperateTime(new Date());
        updateWithChild(before,after);
    }



    /**
     * 修改本部门及子部门的level
     * @param before
     * @param after
     */
    @Transactional(rollbackFor = Exception.class)
    private void updateWithChild(SysDept before, SysDept after) {
        String newLevelPrefix=after.getLevel();
        String oldLevelPrefix=before.getLevel();
        //需要更新子部门的level
        if(!newLevelPrefix.equals(oldLevelPrefix)){
            List<SysDept> sysDeptList=sysDeptMapper.getSysDeptListByLevel(before.getLevel());
            if(!CollectionsUtil.isEmpty(sysDeptList)){
                for(SysDept sysDept:sysDeptList){
                    String level=sysDept.getLevel();
                    if(level.indexOf(oldLevelPrefix)==0){
                        sysDept.setLevel(newLevelPrefix+level.substring(oldLevelPrefix.length()));
                    }
                }
                sysDeptMapper.updateBatchLevel(sysDeptList);
            }
        }
        sysDeptMapper.updateById(after);
    }

    /**
     * 检查同级下部门名称是否重复
     * @param parentId
     * @param deptName
     * @param deptId
     * @return
     */
    private boolean checkExist(Integer parentId,String deptName,Integer deptId){

        return sysDeptMapper.countParentIdAndName(parentId,deptName,deptId)>0;
    }

    private String getLevel(Integer deptId){
        SysDept sysDept=sysDeptMapper.selectById(deptId);
        if(sysDept==null){
            return null;
        }
        return sysDept.getLevel();

    }

    /**
     * 删除部门
     * @param deptId
     */
    @Override
    public void delete(Integer deptId) {
        SysDept sysDept=sysDeptMapper.selectById(deptId);
        Preconditions.checkNotNull(sysDept,"待删除的部门不存在");
        if(sysDeptMapper.countByParentId(deptId)>0){
            throw new ParamException("当前部门下有子部门，无法进行删除");
        }
        if(sysUserMapper.countByDeptId(deptId)>0){
            throw new ParamException("当前部门下有用户，无法进行删除");
        }
        sysDeptMapper.deleteById(deptId);
    }
}
